﻿using AutoMapper;
using Journeo_backend.Configuration;
using static Journeo_backend.Services.Interfaces.IUserService;

namespace Journeo_backend.Services.Implementations
{
    public class UserService : IUserService
    {
        private readonly IMapper _mapper;
        private readonly ApplicationDbContext _context;
        private readonly JwtHelper _jwtHelper;
        private readonly RedisService _redisService; 
        private readonly IConfiguration _configuration;
        private readonly IEmailService _emailService;

        public UserService(
            IMapper mapper,
            ApplicationDbContext context,
            JwtHelper jwtHelper,
            RedisService redisService,
            IConfiguration configuration,
            IEmailService emailService)
        {
            _mapper = mapper;
            _context = context;
            _jwtHelper = jwtHelper;
            _redisService = redisService;
            _configuration = configuration;
            _emailService = emailService;
        }

        // 用户注册
        public async Task<Response<string>> RegisterAsync(UserRegisterDTO userRegisterDTO)
        {
            try
            {
                User user = _mapper.Map<User>(userRegisterDTO);

                // 检查用户名是否已存在
                if (await _context.User.AnyAsync(u => u.Username == user.Username))
                {
                    return new Response<string>("error", Messages.USERNAME_EXISTS);
                }

                // 检查邮箱是否已存在
                if (await _context.User.AnyAsync(u => u.Email == user.Email))
                {
                    return new Response<string>("error", Messages.EMAIL_EXISTS);
                }

                // 检查验证码是否正确
                if (!await VerifyCodeAsync(userRegisterDTO.Email, userRegisterDTO.Code, VerificationType.Register))
                {
                    return new Response<string>("error", "Verification code is incorrect or expired");
                }

                // 添加默认头像
                user.AvatarUrl = "default";

                _context.User.Add(user);

                await _context.SaveChangesAsync();
                return new Response<string>("success", Messages.USER_REGISTERED);
            }
            catch (Exception e)
            {
                return new Response<string>("error", e.Message);
            }
        }

        // 用户登录
        public async Task<Response<UserLoginVO>> LoginAsync(UserLoginDTO loginDTO)
        {
            try
            {
                // 通过邮箱查找用户
                User user = await _context.User.FirstOrDefaultAsync(u => u.Email == loginDTO.Email);
                if (user == null)
                {
                    return new Response<UserLoginVO>("error", Messages.USER_NOT_FOUND);
                }

                // 验证密码
                if (user.Password != loginDTO.Password)
                {
                    return new Response<UserLoginVO>("error", Messages.PASSWORD_INCORRECT);
                }

                // 更新最后登录时间
                user.LastLogin = DateTime.Now;

                // JWT
                var token = _jwtHelper.GetJwtToken(user);

                await _context.SaveChangesAsync();
                return new Response<UserLoginVO>(new UserLoginVO
                {
                    UserId = user.UserId,
                    Status = "success",
                    Token = token
                });
            }
            catch (Exception e)
            {
                return new Response<UserLoginVO>("error", e.Message);
            }
        }

        // 用户密码重置
        public async Task<Response<string>> ForgetPasswordAsync(UserForgetPasswordDTO forgetPasswordDTO)
        {
            try
            {
                // 通过邮箱查找用户
                User user = await _context.User.FirstOrDefaultAsync(u => u.Email == forgetPasswordDTO.Email);
                if (user == null)
                {
                    return new Response<string>("error", Messages.USER_NOT_FOUND);
                }

                // 检查验证码是否正确
                if (!await VerifyCodeAsync(forgetPasswordDTO.Email, forgetPasswordDTO.Code, VerificationType.ResetPassword))
                {
                    return new Response<string>("error", "Verification code is incorrect or expired");
                }

                // 更新密码
                user.Password = forgetPasswordDTO.NewPassword;
                user.UpdatedAt = DateTime.Now;

                await _context.SaveChangesAsync();
                return new Response<string>("success", Messages.PASSWORD_RESET);
            }
            catch (Exception e)
            {
                return new Response<string>("error", e.Message);
            }
        }

        // 获取用户信息
        public async Task<Response<UserInfoVO>> GetUserAsync(long userId)
        {
            User user = await _context.User.FirstOrDefaultAsync(u => u.UserId == userId);
            if (user == null)
            {
                return new Response<UserInfoVO>("error", Messages.USER_NOT_FOUND);
            }

            UserInfoVO userInfoVO = _mapper.Map<UserInfoVO>(user);

            return new Response<UserInfoVO>(userInfoVO);
        }

        // 用户更新
        public async Task<Response<string>> UpdateUserAsync(UserUpdateDTO updateDTO)
        {
            try
            {
                // 通过UserId查找用户
                User user = await _context.User.FirstOrDefaultAsync(u => u.UserId == updateDTO.UserId);
                if (user == null)
                {
                    return new Response<string>("error", Messages.USER_NOT_FOUND);
                }

                // 若传入了Username，检查用户名是否已存在
                if (!string.IsNullOrEmpty(updateDTO.Username) && await _context.User.AnyAsync(u => u.Username == updateDTO.Username && u.UserId != updateDTO.UserId))
                {
                    return new Response<string>("error", Messages.USERNAME_EXISTS);
                }

                // 若传入了Email，检查邮箱是否已存在
                if (!string.IsNullOrEmpty(updateDTO.Email) && await _context.User.AnyAsync(u => u.Email == updateDTO.Email && u.UserId != updateDTO.UserId))
                {
                    return new Response<string>("error", Messages.EMAIL_EXISTS);
                }

                // 更新用户信息
                if (!string.IsNullOrEmpty(updateDTO.Username))
                {
                    user.Username = updateDTO.Username;
                }

                if (!string.IsNullOrEmpty(updateDTO.Email))
                {
                    user.Email = updateDTO.Email;
                }

                if (!string.IsNullOrEmpty(updateDTO.Password))
                {
                    user.Password = updateDTO.Password;
                }

                if (!string.IsNullOrEmpty(updateDTO.AvatarUrl))
                {
                    user.AvatarUrl = updateDTO.AvatarUrl;
                }

                user.UpdatedAt = DateTime.Now;

                await _context.SaveChangesAsync();
                return new Response<string>("success", Messages.USER_UPDATED);
            }
            catch (Exception e)
            {
                return new Response<string>("error", e.Message);
            }
        }

        // 用户头像上传base64
        public async Task<Response<string>> UploadAvatarAsync(long userId, string base64Image)
        {
            try
            {
                var user = await _context.User.FirstOrDefaultAsync(u => u.UserId == userId);
                if (user == null)
                {
                    return new Response<string>("error", Messages.USER_NOT_FOUND);
                }

                var url = $"avatar:{userId}";
                user.AvatarUrl = url;

                var response = await _redisService.UploadImageAsync(url, base64Image);
                if (response.Status == "error")
                {
                    return new Response<string>("error", response.Message);
                }

                await _context.SaveChangesAsync();
                return new Response<string>(url);
            }
            catch (Exception e)
            {
                return new Response<string>("error", e.Message);
            }
        }

        // 用户头像下载base64
        public async Task<Response<string>> GetAvatarAsync(long userId)
        {
            var user = await _context.User.FirstOrDefaultAsync(u => u.UserId == userId);
            if (user == null)
            {
                return new Response<string>("error", Messages.USER_NOT_FOUND);
            }

            var response = await _redisService.GetImageAsync(user.AvatarUrl);
            if (response.Status == "error")
            {
                return new Response<string>("error", response.Message);
            }

            return new Response<string>(response.Data);
        }

        // 用户头像上传file
        public async Task<Response<string>> UploadAvatarAsync(long userId, IFormFile file)
        {
            try
            {
                var user = await _context.User.FirstOrDefaultAsync(u => u.UserId == userId);
                if (user == null)
                {
                    return new Response<string>("error", Messages.USER_NOT_FOUND);
                }

                var url = $"avatar:{userId}";
                user.AvatarUrl = url;

                var response = await _redisService.UploadImageAsync(url, file);
                if (response.Status == "error")
                {
                    return new Response<string>("error", response.Message);
                }

                await _context.SaveChangesAsync();
                return new Response<string>(url);
            }
            catch (Exception e)
            {
                return new Response<string>("error", e.Message);
            }
        }

        // 发送验证码
        public async Task<Response<string>> SendVerificationCodeAsync(string email, VerificationType type)
        {
            try
            {
                // 检查邮箱格式
                if (!IsValidEmail(email))
                {
                    return new Response<string>("error", "Invalid email format");
                }

                // 根据验证类型检查邮箱
                if (type == VerificationType.Register)
                {
                    // 注册时，检查邮箱是否已存在
                    if (await _context.User.AnyAsync(u => u.Email == email))
                    {
                        return new Response<string>("error", Messages.EMAIL_EXISTS);
                    }
                }
                else if (type == VerificationType.ResetPassword)
                {
                    // 重置密码时，检查邮箱是否存在
                    if (!await _context.User.AnyAsync(u => u.Email == email))
                    {
                        return new Response<string>("error", Messages.USER_NOT_FOUND);
                    }
                }

                // 生成6位数验证码
                string verificationCode = GenerateVerificationCode();

                // 构建 Redis key
                string redisKey = $"verification:{type}:{email}";

                // 将验证码保存到Redis，设置5分钟过期
                await _redisService.SetVerificationCodeAsync(redisKey, verificationCode);

                // 发送邮件
                string subject = type == VerificationType.Register ? "注册验证码" : "重置密码验证码";
                string body = $"您的验证码是：{verificationCode}，有效期5分钟，请勿泄露给他人。";

                await _emailService.SendEmailAsync(email, subject, body);

                return new Response<string>("success", "Verification code sent successfully");
            }
            catch (Exception e)
            {
                return new Response<string>("error", e.Message);
            }
        }


        // 验证验证码
        public async Task<bool> VerifyCodeAsync(string email, string code, VerificationType type)
        {
            try
            {
                string redisKey = $"verification:{type}:{email}";

                // 从Redis获取验证码
                string storedCode = await _redisService.GetVerificationCodeAsync(redisKey);

                if (string.IsNullOrEmpty(storedCode))
                {
                    return false;
                }

                // 验证码比较
                if (storedCode != code)
                {
                    return false;
                }

                // 验证成功后删除Redis中的验证码
                await _redisService.DeleteVerificationCodeAsync(redisKey);

                return true;
            }
            catch (Exception e)
            {
                return false;
            }
        }



        private string GenerateVerificationCode()
        {
            Random random = new Random();
            return random.Next(100000, 999999).ToString();
        }

        private bool IsValidEmail(string email)
        {
            try
            {
                var addr = new System.Net.Mail.MailAddress(email);
                return addr.Address == email;
            }
            catch
            {
                return false;
            }
        }
    }
}
